<template>
  <div>
    <div class="container">
      <!-- 页面容器 -->
      <div class="wrapper">
        <!-- 面包屑 -->
        <el-breadcrumb
          class="breadcrumb"
          separator=">"
        >
          <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
          <el-breadcrumb-item
            :to="
              {
                name: 'category',
                params: {
                  id: subCategoryFilterList.parentId
                }
              }"
          >
            {{ subCategoryFilterList.parentName }}
          </el-breadcrumb-item>
          <el-breadcrumb-item >{{ subCategoryFilterList.name }}</el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 筛选规格 -->
        <div class="choose">
          <!-- 品牌 -->
          <div class="choose-item">
            <div class="choose-head">品牌：</div>
            <div class="choose-body">
              <a
                :class="findCategorySubName({name: '品牌'}, '全部') ? 'all active' : 'all'"
                @click="onclick({name: '品牌'}, {name: '全部'})"
              >
                全部
              </a>
              <a
                :class="findCategorySubName({name: '品牌'}, brand.name) ? 'property active' : 'property'"
                @click="onclick({name: '品牌'}, brand)" v-for="brand in subCategoryFilterList.brands"
                :key="brand.id"
              >
                {{ brand.name }}
              </a>
            </div>
          </div>
          <div class="choose-item" v-for="item in subCategoryFilterList.saleProperties" :key="item.id">
            <div class="choose-head">{{ item.name }}</div>
            <div class="choose-body">
              <a
                :class="findCategorySubName(item, '全部') ? 'all active' : 'all'"
                @click="onclick(item, {name: '全部'})"
              >
                全部
              </a>
              <a
                :class="findCategorySubName(item, property.name) ? 'property active' : 'property'"
                @click="onclick(item, property)" v-for="property in item.properties"
                :key="property.id">
                {{ property.name }}
              </a>
            </div>
          </div>

        </div>
        <!-- 懒加载 -->
        <div class="goods-list">
          <div class="goods-head-wrapper">
            <div class="btn-wrapper">
              <el-row>
                <button
                  :class="activeShow === 'default' ? 'btn-active' : ''"
                  @click="selectSort('default')"
                >
                  默认排序
                </button>
                <button
                  :class="activeShow === 'publishTime' ? 'btn-active' : ''"
                  @click="selectSort('publishTime')"
                >
                  最新商品
                </button>
                <button
                  :class="activeShow === 'orderNum' ? 'btn-active' : ''"
                  @click="selectSort('orderNum')"
                >
                  最高人气
                </button>
                <button
                  :class="activeShow === 'evaluateNum' ? 'btn-active' : ''"
                  @click="selectSort('evaluateNum')"
                >
                  评论最多
                </button>
                <button
                  @click="selectSort('price')"
                >
                  <div>价格排序</div>
                  <div class="select-icon">
                    <el-icon :class="priceSort === 'asc' ? 'active-top' : 'color-top'"><CaretTop /></el-icon>
                    <el-icon :class="priceSort === 'desc' ? 'active-bottom' : 'color-bottom'"><CaretBottom /></el-icon>
                  </div>
                </button>
                <sort-button
                  v-model:value="sortType"
                >
                  价格排序
                </sort-button>
              </el-row>
            </div>
            <div class="inp">
              <input type="checkbox" @click="onClickInventory">
              仅显示有货商品
              <input type="checkbox" @click="onClickDiscount">
              仅显示特惠商品
            </div>
          </div>
          <div class="card-container" v-if="!subCategoryGoodsShow">
            <div
              class="box-card"
              v-for="o in subCategoryGoods.items"
              :key="o.id"
              @click="toGoodsDetail(o.id)"
            >
              <div class="card-img">
                <img :src="o.picture" alt="">
              </div>
              <div class="card-name">{{ o.name }}</div>
              <div class="card-desc">{{ o.desc }}</div>
              <div class="card-price">￥{{ o.price }}</div>
            </div>
          </div>
          <div class="last-observer" style="width: 100%;"></div>
        </div>
        <el-empty
          :image-size="200"
          v-if="!hasNext"
          description="亲！没有更多了"
        />
      </div>
    </div>
  </div>
</template>
<script setup>
import { useStore } from 'vuex';
import { ref } from 'vue';
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
import { computed } from 'vue';
import SortButton from '@/components/SortButton/index.vue';
const router = useRouter();
const route = useRoute();
const store = useStore();
const sortType = ref('');
// 商品二级分类懒加载
const currentPage = ref(1);
const subCategoryGoods = ref({});
const subCategoryFilterList = ref({});
const categorySelectList = ref([]);
const subCategoryGoodsShow = ref(false);
// 分页信息
const pageInfo = {
  page: currentPage.value,
  pageSize: 10,
  categoryId: '',
};
// 封装查找是否为选中状态函数（实现选中高亮）
function findCategorySubName(category, subName) {
  const exits = categorySelectList.value
    .find((item) => (
      item.group?.name === category.name &&
      item.group?.id === category.id &&
      item.propertyName === subName
    ));
  return exits;
}

async function resetSubCategoryGoods(params) {
  // 重置请求
  await store.dispatch('category/resetSubCategoryGoods', params);
  const data = computed(() => store.state.category.subCategoryGoods);
  subCategoryGoods.value = data.value;
}

// 点击事件
function onclick(category, property) {
  // 找出相同分类的索引 categorySelectList 数组项的数据类型为proxy 跟品牌的数据类型不同，不能直接判断，因此要同时判断name 和 id
  const index = categorySelectList.value.findIndex((item) => item.group?.name === category.name && item.group?.id === category.id);
  if (index >= 0) {
    // 索引大于等于0时，修改选中属性 （改变高亮的值）
    categorySelectList.value[index].propertyName = property.name;
  } else {
    // 就push新选中的属性
    categorySelectList.value.push({ group: category, propertyName: property.name });
  }

  // 根据筛选条件重新请求
  // 重置当前页码为第一页
  currentPage.value = 1;
  // 更新分页信息
  pageInfo.page = currentPage.value;
  // 提取选中属性 生成新的传参数组
  const params = categorySelectList.value.
    map((item) => ({ groupName: item.group?.name, propertyName: item.propertyName }))
    .filter((tmp) => tmp.propertyName !== '全部'); // 剔出 分组为 ‘全部’ 的属性
  resetSubCategoryGoods({ ...pageInfo, attrs: params });
}

// 懒加载按钮默认值
const activeShow = ref('default');
const priceSort = ref('');

// 排序按钮点击事件
// 点击改变属性
function selectSort(value) {
  activeShow.value = value;
  // 重置当前页码为第一页
  currentPage.value = 1;
  // 更新分页信息
  pageInfo.page = currentPage.value;
  const params = {
    sortField: value,
    sortMethod: null,
  };
  // 价格排序判断
  if (value === 'price') {
    if (priceSort.value === 'desc') {
      priceSort.value = 'asc';
    } else {
      priceSort.value = 'desc';
    }
    params.sortMethod = priceSort.value;
  } else {
    priceSort.value = '';
  }
  // 请求数据
  resetSubCategoryGoods({ ...pageInfo, ...params });
};
const onlyDiscount = ref(false);
// 点击特惠
function onClickDiscount() {
  onlyDiscount.value = !onlyDiscount.value;
  currentPage.value = 1;
  pageInfo.page = currentPage.value;

  resetSubCategoryGoods({ ...pageInfo, onlyDiscount: onlyDiscount.value });
}

const inventory = ref(false);
// 点击有货
function onClickInventory() {
  inventory.value = !inventory.value;
  currentPage.value = 1;
  pageInfo.page = currentPage.value;
  resetSubCategoryGoods({ ...pageInfo, inventory: inventory.value });
}


// 封装懒加载更新数据更新请求函数
async function updateData(params) {
  // 懒加载请求
  await store.dispatch('category/updateSubCategoryGoods', params);
  const res = computed(() => store.state.category.subCategoryGoods);
  subCategoryGoods.value = res.value;
}


// 页面初始化或者id变化时需要做的
async function init(to) {
  currentPage.value = 1;
  pageInfo.categoryId = to.params.id;
  await store.dispatch('category/updateCategoryFilterList', to.params.id);
  const res = await computed(() => store.state.category.subCategoryFilterGoods);
  subCategoryFilterList.value = res.value;

  // 初始默认选中的数据，通过数据渲染实现默认高亮
  categorySelectList.value = res.value.saleProperties.map((item) => ({ group: item, propertyName: '全部' }));
  categorySelectList.value.push({ group: { name: '品牌' }, propertyName: '全部' });

  // 初始化商品列表
  await resetSubCategoryGoods(pageInfo);
}
// 初始化请求
init(route);
// 路由id变化时, 重新请求
onBeforeRouteUpdate(init);

// 记录
let observer = null; // 记录元素的变化
let lastObserver = null; // 检测最后一个元素
const hasNext = computed(() => subCategoryGoods.value.pages > currentPage.value); // 记录是否有下一页

// 监听数据变化
watch(subCategoryGoods, async () => {
  await nextTick();
  // 取消上一轮的观察
  if (observer) {
    observer.unobserve(lastObserver);
  }
  if (!hasNext.value) {
    return;
  }
  // 当observer滚动到视野中时, dispatch
  observer = new IntersectionObserver(
    (entries) => {
      if (entries[0].isIntersecting) {
        pageInfo.page = ++currentPage.value;
        updateData(pageInfo); // 更新数据
      }
    },
    {
      root: null,
      rootMargin: '0px',
      threshold: 0.5,
    },
  );
  lastObserver = document.querySelector('.last-observer');
  // 启动观察lastObserver是否进入视野
  observer.observe(lastObserver);
});

function toGoodsDetail(id) {
  router.push({
    name: 'product',
    params: {
      id,
    },
  });
}


</script>
<style lang="scss" scoped>
.container{
  background-color: #f5f5f5;
  .wrapper{
    box-sizing: border-box;
    padding: 25px 10px;
    width: 1240px;
    margin: 0 auto;
    // 面包屑
    .breadcrumb{
      margin-bottom: 20px;
      font-size: 14px;
      color: #999;
      .el-breadcrumb__item{
        color: #999;
      }
    }
    // 筛选规格
    .choose{
      width: 1240px;
      background: #fff;
      padding: 25px;
      box-sizing: border-box;
      .choose-item{
        display: flex;
        font-size: 14px;
        .choose-head{
          width: 80px;
          line-height: 40px;
          color: #999;
        }
        .choose-body{
          flex: 1;
          .all{
              margin-right: 36px;
              display: inline-block;
              transform: translateY(-15px);
              max-width: 112px;
              line-height: 40px;
              // color: #27ba9b;
              cursor: pointer;
            }
           .property{
              margin-right: 36px;
              display: inline-block;
              transition: all .3s;
              max-width: 112px;
              line-height: 40px;
              text-overflow: ellipsis;
              overflow: hidden;
              white-space: nowrap;
              cursor: pointer;
            }
            .property:hover{
              color: #27ba9b;
            }
            .active{
              color: #27ba9b;
            }
          }
        }
    }
    // 商品列表
    .goods-list{
      width: 1240px;
      box-sizing: border-box;
      background: #fff;
      margin: 25px auto;
      padding: 0 25px;
      .goods-head-wrapper{
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: 1190px;
        height: 80px;
        .btn-wrapper{
          button{
            display: flex;
            justify-content: center;
            align-items: center;
            color: #999;
            outline: none;
            border: 1px solid #e4e4e4;
            margin-right: 25px;
            width: 98px;
            height: 30px;
            border-radius: 2px;
            background: #fff;
            cursor: pointer;
          }
          .btn-active {
            background-color: #27ba9b;
            border: 1px solid #27ba9b;
            color: #fff;
          }
          .select-icon{
            display: flex;
            flex-direction: column;
            .color-top{
              transform: translateY(3px);
            }
            .color-bottom{
              transform: translateY(-3px);
            }
            .active-top{
              color: #27ba9b;
              transform: translateY(3px);
            }
            .active-bottom{
              color: #27ba9b;
              transform: translateY(-3px);
            }
          }
        }
        .inp{
          font-size: 14px;
          color: #999;
          input{
            margin: 0;
            outline: none;
            border: 1px solid #e4e4e4;
            margin-left: 20px;
          }
        }
      }
      .card-container{
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        gap: 20px;
        .box-card{
          padding: 20px 30px;
          box-sizing: border-box;
          width: 220px;
          display: flex;
          flex-direction: column;
          align-items: center;
          text-align: center;
          transition: all 200ms linear;

          .card-img{
            img{
              width: 160px;
              height: 160px;
            }
          }
          .card-name{
            width: 160px;
            padding-top: 10px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            text-align: center;
          }

          .card-desc{
            width: 160px;
            padding-top: 10px;
            color: #999;
            font-size: 14px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            text-align: center;
          }
          .card-price{
            width: 160px;
            padding-top: 10px;
            color: #cf4444;
            font-size: 20px;
            text-align: center;
          }
          &:hover{
            box-shadow: 0 3px 10px #ccc;
            transform: translateY(-4px);
          }
        }
      }
    }
  }
}


</style>

